package com.ruoyi.mof.util;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.RSAUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.annotation.adapters.HexBinaryAdapter;

/**
 * @author Fei.Cong
 * @date 2023-09-08 10:27
 */
@Slf4j
public class DesUtil {

    /**
     * 返回加密后的证照id密文和key
     *
     * @param certid          证照的唯一标识ID赋码
     * @param publicKeyString 公钥字符串（部里单独提供给省里）
     * @return
     */
    public static JSONObject encryption(String certid, String publicKeyString) {
        JSONObject rtnObj = new JSONObject();
        try {
            // 随机生成8个字符的字符串（以下key值只是示例，可以指定或者随机生成）
//            String key = "12345678";
            String key = RandomStringUtils.randomAlphanumeric(8);
            // 生成密钥对象,如果算法是DES，那么这个构造函数不会检查key是否为8个字节长
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(), "DES");
            // 获取加解密实例
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            // 初始化加密模式
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

            // 加密
            byte[] ecertidByte = cipher.doFinal(certid.getBytes());
            // HexBinaryAdapter十六进制转换工具,把 byte 数据转换成十六进制的字符串表示。
            HexBinaryAdapter hexBinaryAdapter = new HexBinaryAdapter();
            //返回的ID密文
            rtnObj.put("encryCertid", hexBinaryAdapter.marshal(ecertidByte));
            // 将随机字符串用ras加密
            String encryKey = RSAUtil.encrypt(key, publicKeyString);
            //返回的key密文
            rtnObj.put("encryKey", encryKey);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
//            throw new ServiceException("加密失败" + e);
        }
        return rtnObj;
    }

    /**
     * 解密
     *
     * @param encryCertid      加密后的证照的唯一标识
     * @param encryKey         ras加密后的key
     * @param privateKeyString 私钥
     */
    public static JSONObject decryption(String encryCertid, String encryKey,
                                        String privateKeyString) {
        JSONObject rtnObj = new JSONObject();
        try {
            // 先将key进行ras解密
            String decryKey = RSAUtil.decrypt(encryKey, privateKeyString);

            // 生成密钥对象,如果算法是DES，那么这个构造函数不会检查key是否为8个字节长
            SecretKeySpec secretKeySpec = new SecretKeySpec(decryKey.getBytes(), "DES");
            // 获取加解密实例
            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
            // 初始化解密模式
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            // HexBinaryAdapter十六进制转换工具
            HexBinaryAdapter hexBinaryAdapter = new HexBinaryAdapter();
            // 解密
            byte[] ecertidResult = cipher.doFinal(hexBinaryAdapter.unmarshal(encryCertid));
            // 结果
            rtnObj.put("certid", new String(ecertidResult));
            rtnObj.put("decryKey", decryKey);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new ServiceException("解密失败" + e);
        }
        return rtnObj;
    }
}
